package com.example.onlineproject.service.impl;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.onlinecommon.utils.TimeUtil;
import com.example.onlineproject.entry.ApplyOrder;
import com.example.onlineproject.mapper.ApplyOrderMapper;
import com.example.onlineproject.service.ApplyOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;



@Service
@Slf4j
public class ApplyOrderServiceImpl extends ServiceImpl<ApplyOrderMapper, ApplyOrder> implements ApplyOrderService {



    @Value("${alipay.appId}")
    private String appId;

    @Value("${alipay.privateKey}")
    private String privateKey;

    @Value("${alipay.publicKey}")
    private String publicKey;

    @Value("${alipay.gatewayUrl}")
    private String gateway;

    @Value("${spring.interface.ip}")
    private String ip;

    @Value("${server.port}")
    private String port;

    @Value("${alipay.notifyUrl}")
    private String notifyUrl;

    @Autowired
    private ApplyOrderMapper applyOrderMapper;

    /**
     *  根据订单id 获取该订单的支付信息
     * @param id
     * @return
     */
    public ApplyOrder getApplyOrderCode(Long id){
        ApplyOrder applyOrder = applyOrderMapper.selectById(id);
        applyOrder = aliPay(applyOrder);
        return applyOrder;
    }

    /**
     *  1. 二维码有效期：默认2小时（计算时间是生成二维码链接开始计算）
     *  2. 电脑网站支付生成的二维码，有效期默认为1分钟。
     *  3. A用户使用支付宝扫码二维码生成订单后 ，B用户再去扫描同一二维码则会报“二维码已失效，请商家更换二维码后重新支付”
     * @param order
     * @return
     */
    public ApplyOrder aliPay(ApplyOrder order) {
        String shopName = order.getShopName();
        String orderNo = order.getOrderNo();
        String price = order.getPrice();

        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        // 支付请求
        request.setBizContent("{" +
                "    \"out_trade_no\":\"" + orderNo + "\"," +//商户订单号
                "    \"total_amount\":\"" + price + "\"," +
                "    \"subject\":\"" + shopName + "当面付" + "\"," +
                "    \"store_id\":\"00100\"," + // (必填) 商户门店编号，通过门店号和商家后台可以配置精准到门店的折扣信息，详询支付宝技术支持
                "    \"timeout_express\":\"5m\"}");//订单允许的最晚付款时间
        AlipayTradePrecreateResponse response = null;

        String url = "http://" + ip + ":" + notifyUrl;  // 需要经过网关的   http://127.0.0.1:88/api/project/applyController/notify
        request.setNotifyUrl(url); // 接口通知方式

        //支付宝二维码URL
        String qrCode = "";
        AlipayClient alipayClient = new DefaultAlipayClient(gateway, appId, privateKey, "json", "utf-8", publicKey, "RSA2");
        try {
            response = alipayClient.execute(request);
            if(response.isSuccess()){
                System.out.println("调用成功");
            } else {
                System.out.println("调用失败");
            }
            if (!response.isSuccess()) {
                throw new Exception("生成支付宝订单失败:" + response.getMsg());
            }
            qrCode = response.getQrCode();
        }  catch (Exception e) {
            e.printStackTrace();
        }
        order.setCodeUrl(qrCode);
        LocalDateTime currentTime = TimeUtil.getCurrentTime();
        order.setUpdateTime(currentTime);

        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.eq("id", order.getId());
        updateWrapper.set("code_url", qrCode);
        updateWrapper.set("update_time", currentTime);
        applyOrderMapper.update(null, updateWrapper);
        return order;
    }


    /**
     * 回调方法必须调用的验签方法，在回调结果前调用，确保是由支付宝发起的请求
     * @return boolean
     */
    public  boolean checkSign(Map<String,String[]> requestParams){
        Map<String,String> params = new HashMap<String,String>();//将异步通知中收到的所有参数都存放到 map 中
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }
        boolean signVerified = false; //调用SDK验证签名
        try {
            signVerified = AlipaySignature.rsaCheckV1(params, publicKey, "utf-8", "RSA2");
        } catch (AlipayApiException e) {
            log.error("支付宝验签接口请求失败，resp={}", e.getErrMsg());
        }
        return signVerified;
    }

}
